package com.example.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.Semaphore;

@Service
@Slf4j
public class SemaphorePrintABCService {

    private final Semaphore semaphoreA = new Semaphore(3); // A 线程需要获取 3 次许可
    private final Semaphore semaphoreB = new Semaphore(0); // B 线程需要获取 2 次许可
    private final Semaphore semaphoreC = new Semaphore(0); // C 线程需要获取 1 次许可
    private static final int TOTAL_CYCLES = 5;

    public void printABCSequence() {
        Thread threadA = new Thread(this::printA);
        Thread threadB = new Thread(this::printB);
        Thread threadC = new Thread(this::printC);

        threadA.start();
        threadB.start();
        threadC.start();

        try {
            threadA.join();
            threadB.join();
            threadC.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.error("主线程被中断", e);
        }

        log.info("所有循环已完成，任务结束");
    }

    private void printA() {
        for (int cycle = 0; cycle < TOTAL_CYCLES; cycle++) {
            try {
                for (int i = 0; i < 3; i++) {
                    semaphoreA.acquire(); // 获取许可打印 A
                    log.info("A");
                }
                semaphoreB.release(2); // 打印完 A 唤醒 B
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.error("线程A被中断", e);
            }
        }
    }

    private void printB() {
        for (int cycle = 0; cycle < TOTAL_CYCLES; cycle++) {
            try {
                semaphoreB.acquire(2); // 获取 2 次许可打印 B
                for (int i = 0; i < 2; i++) {
                    log.info("B");
                }
                semaphoreC.release(); // 打印完 B 唤醒 C
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.error("线程B被中断", e);
            }
        }
    }

    private void printC() {
        for (int cycle = 0; cycle < TOTAL_CYCLES; cycle++) {
            try {
                semaphoreC.acquire(); // 获取许可打印 C
                log.info("C");
                semaphoreA.release(3); // 打印完 C 唤醒 A
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.error("线程C被中断", e);
            }
        }
    }
}
